<template>
	<div class="recruit-container">
		<!-- 顶部导航 - 统一样式 -->
		<div class="header">
			<button class="back-btn" @click="goBack">← 返回</button>
			<div class="header-center">
				<div class="title">伙伴招募</div>
			</div>
			<div class="placeholder"></div>
		</div>

		<!-- 玩家资源面板 - 压缩版 -->
		<div class="currency-panel">
			<div class="currency-row">
				<div class="currency-item">
					<span class="currency-icon coin1">银</span>
					<span class="currency-value">{{ $store.getters['items/coin'] }}</span>
				</div>
				<div class="currency-item">
					<span class="currency-icon coin2">金</span>
					<span class="currency-value">{{ $store.getters['items/goldCoin'] }}</span>
				</div>
				<div class="currency-item">
					<span class="currency-icon">令</span>
					<span class="currency-value">{{ $store.getters['items/inviteLing'] }}</span>
				</div>
				<div class="currency-item">
					<span class="currency-icon">分</span>
					<span class="currency-value">{{ $store.getters['items/inviteScore'] }}</span>
				</div>
			</div>
		</div>

		<!-- 页面主体招募模块 - 压缩版 -->
		<div class="recruit-options">
			<!-- 网络错误提示 -->
			<div class="error-notice" v-if="networkError">
				<div class="error-content">
					<text class="error-icon">⚠️</text>
					<text class="error-text">网络连接异常，部分功能可能受限</text>
					<div class="error-actions">
						<div class="retry-btn" @click="retryLoadData">
							<text>重试</text>
						</div>
					</div>
				</div>
			</div>

			<!-- 普通招募卡片（银两） -->
			<div class="recruit-card normal-recruit">
				<div class="card-header">
					<div class="card-title">普通招募</div>
				</div>
				<div class="card-content">
					<div class="cost-display">
						<span class="cost-label">消耗：</span>
						<span class="cost-value">银两 {{ normalSpeedOne }}/次</span>
					</div>
					<div class="recruit-buttons">
						<button class="recruit-btn primary-btn" :class="{ disabled: !checkResources('normal', 1) }" @click="recruit('normal', 1)">
							<span class="btn-text">单次</span>
							<span class="btn-cost">{{ normalSpeedOne }}</span>
						</button>
						<button class="recruit-btn primary-btn ten-recruit" :class="{ disabled: !checkResources('normal', 10) }" @click="recruit('normal', 10)">
							<span class="btn-text">十连</span>
							<span class="btn-cost">{{ normalSpeedTen }}</span>
							<span class="btn-bonus">必出蓝+</span>
						</button>
					</div>
				</div>
			</div>

			<!-- 高级招募卡片（优先消耗招募令） -->
			<div class="recruit-card premium-recruit">
				<div class="card-header">
					<div class="card-title">高级招募</div>
				</div>
				<div class="card-content">
					<div class="cost-display">
						<span class="cost-label">消耗：</span>
						<span class="cost-value" v-if="$store.getters['items/inviteLing'] > 0">招募令 1/次</span>
						<span class="cost-value" v-else>金元宝 {{ advancedSpeedOne }}/次</span>
					</div>
					<div class="recruit-buttons">
						<button class="recruit-btn premium-btn" :class="{ disabled: !checkResources('advanced', 1) }" @click="recruit('advanced', 1)">
							<span class="btn-text">单次</span>
							<span class="btn-cost">{{ ($store.getters['items/inviteLing'] || 0) > 0 ? '1' : advancedSpeedOne }}</span>
						</button>
						<button class="recruit-btn premium-btn ten-recruit" :class="{ disabled: !checkResources('advanced', 10) }" @click="recruit('advanced', 10)">
							<span class="btn-text">十连</span>
							<span class="btn-cost">{{ ($store.getters['items/inviteLing'] || 0) > 0 ? '10' : advancedSpeedTen }}</span>
							<span class="btn-bonus">必出紫+</span>
						</button>
					</div>
				</div>
			</div>
			
			<!-- 积分兑换区域 -->
			<div class="exchange-section">
				<div class="section-title">积分兑换</div>
				<div class="exchange-content">
					<div class="exchange-card">
						<div class="exchange-info">
							<span class="exchange-name">五阶兑换令</span>
							<span class="exchange-price">{{ exchangeLetterPrice }} 积分/个</span>
						</div>
						<div class="exchange-controls">
							<button class="count-btn" @click="decreaseExchangeCount" :disabled="exchangeCount <= 1">-</button>
							<span class="count-display">{{ exchangeCount }}</span>
							<button class="count-btn" @click="increaseExchangeCount" :disabled="exchangeCount >= maxExchangeCount">+</button>
							<button class="exchange-btn" @click.stop="exchangeLetter" :disabled="loading">兑换</button>
						</div>
					</div>
				</div>
			</div>
			
			<!-- 五阶伙伴兑换区域 -->
			<div class="partner-exchange-section">
				<div class="section-title">五阶伙伴兑换</div>
				<div class="exchange-info-bar">
					<span class="info-label">兑换令：</span>
					<span class="info-value">{{ $store.getters['items/partnerExchangeLetter'] || 0 }}</span>
					<span class="info-divider">|</span>
					<span class="info-text">100个兑换1个</span>
				</div>
				<div class="partner-exchange-list" v-if="exchangePartnerList.length > 0">
					<div 
						v-for="partner in exchangePartnerList" 
						:key="partner.partner_id" 
						class="partner-exchange-card"
					>
						<div class="partner-name pev-5">{{ partner.partner_name }}</div>
						<div class="partner-desc" v-if="partner.desc || partner.Desc">{{ partner.desc || partner.Desc }}</div>
						<button 
							class="exchange-partner-btn" 
							@click.stop="exchangePartnerConfirm(partner)"
							:disabled="loading"
						>
							兑换
						</button>
					</div>
				</div>
				<div v-else class="no-partner-text">暂无可兑换伙伴</div>
			</div>
			
			<!-- 图鉴按钮 -->
			<div class="bottom-actions">
				<button class="codex-btn" @click="openCodex">📖 伙伴图鉴</button>
			</div>
		</div>

		<!-- 结果弹窗 -->
		<div class="result-modal" v-if="showResult" @click="closeResult">
			<div class="modal-content" @click.stop>
				<div class="modal-header">
					<div class="modal-title">招募结果</div>
					<div class="close-btn" @click="closeResult">×</div>
				</div>
				
				<!-- 招募类型描述 -->
				<div class="result-section recruit-type-section" v-if="recruitResult.recruit_type && recruitResult.recruit_count">
					<div class="recruit-type-text">
						{{ getRecruitTypeName(recruitResult.recruit_type) }}: {{ getRecruitCountText(recruitResult.recruit_count) }}
					</div>
				</div>
				
				<!-- 积分展示区 -->
				<div class="result-section score-section" v-if="recruitResult.current_score !== undefined && recruitResult.current_score !== null">
					<div class="section-title">本次获得积分：{{ recruitResult.current_score }}</div>
				</div>
				
				<!-- 新伙伴展示区 -->
				<div class="result-section partners-section" v-if="recruitResult.partners && recruitResult.partners.length > 0">
					<div class="section-divider"></div>
					<div class="section-title">新获得伙伴</div>
					<div class="partners-list">
						<div v-for="(p, idx) in recruitResult.partners" :key="idx" class="partner-item">
							<span class="partner-name-text" :class="'pev-' + p.pev">{{ p.name }}:品阶{{ p.pev }}</span>
						</div>
					</div>
				</div>
				<div v-else-if="recruitResult.partners && recruitResult.partners.length === 0" class="result-section partners-section">
					<div class="section-divider"></div>
					<div class="no-partners-text">本次招募未获得新伙伴（重复伙伴已转换为积分）</div>
				</div>
				
				<div class="result-actions">
					<div class="result-btn continue-btn" @click="continueRecruit">继续招募</div>
					<div class="result-btn" @click="goToPartners">前往伙伴</div>
				</div>
			</div>
		</div>

		<!-- 图鉴弹窗 -->
		<div class="codex-modal" v-if="showCodex" @click="closeCodex">
			<div class="modal-content codex-content" @click.stop>
				<div class="modal-header">
					<div class="modal-title">📚 江湖伙伴图鉴</div>
					<div class="close-btn" @click="closeCodex">×</div>
				</div>
				<div class="codex-body">
					<!-- 品阶筛选 -->
					<div class="codex-filter">
						<button 
							v-for="pev in [1, 2, 3, 4, 5]" 
							:key="pev"
							class="filter-btn"
							:class="{ active: selectedPev === pev }"
							@click="selectedPev = pev"
						>
							{{ pev + '阶' }}
						</button>
					</div>
					<!-- 伙伴列表 -->
					<div class="codex-list" v-if="codexPartners.length > 0">
						<div 
							v-for="partner in filteredCodexPartners" 
							:key="partner.name"
							class="codex-partner-item"
							:class="{ owned: partner.owned, unowned: !partner.owned }"
						>
							<span 
								class="codex-partner-name"
								:class="partner.owned ? 'pev-' + partner.pev : 'unowned'"
							>
								{{ partner.name }}
							</span>
						</div>
					</div>
					<div v-else class="codex-empty">暂无数据</div>
				</div>
			</div>
		</div>
		
		<!-- 兑换确认弹窗 -->
		<div class="confirm-modal" v-if="showExchangeConfirm" @click="showExchangeConfirm = false">
			<div class="modal-content confirm-content" @click.stop>
				<div class="modal-header">
					<div class="modal-title">确认兑换</div>
					<div class="close-btn" @click="showExchangeConfirm = false">×</div>
				</div>
				<div class="confirm-body">
					<div class="confirm-text">
						确认消耗 <span class="highlight">100</span> 个五阶兑换令兑换 <span class="highlight">{{ currentExchangePartner?.partner_name }}</span> 吗？
					</div>
					<div class="confirm-actions">
						<button class="confirm-btn cancel" @click.stop="showExchangeConfirm = false">取消</button>
						<button class="confirm-btn confirm" @click.stop="doExchangePartner">确认</button>
					</div>
				</div>
			</div>
		</div>

		<!-- 加载遮罩 -->
		<div class="loading-overlay" v-if="loading">
			<div class="loading-content" @click.stop>
				<span class="loading-text">正在处理...</span>
				<div class="loading-animation">
					<span class="loading-dot">•</span>
					<span class="loading-dot">•</span>
					<span class="loading-dot">•</span>
				</div>
			</div>
		</div>

	</div>
</template>

<script>
import QualityText from '@/components/QualityText.vue'
import { ITEM_ID } from '@/store/modules/items'
import { ITEM_NAME } from '@/config/items'
export default {
	components: { QualityText },
	data() {
		return {
			loading: false,
			showResult: false,
			// 招募弹窗交互移除：默认不显示
			showRecruitDialog: false,
			// 货币类型与速度（后端配置）
			coinTypeNormal: 1,
			coinTypeAdvanced: 2,
			normalSpeedOne: 0,
			normalSpeedTen: 0,
			advancedSpeedOne: 0,
			advancedSpeedTen: 0,
			recruitConfig: {
				normal: { cost: { coin1: 100 }, probabilities: { green: 0.6, blue: 0.3, purple: 0.09, orange: 0.01 } },
				advanced: { cost: { coin2: 100 }, probabilities: { green: 0.3, blue: 0.4, purple: 0.25, orange: 0.05 } },
				duplicate_points: { green: 2, blue: 4, purple: 8, orange: 16 }
			},
			networkError: false,
			recruitResult: { partners: [], new_count: 0, recruit_type: '', recruit_count: 0, cost: {}, invite_score: 0 },
			// 新增：配置加载标记，确保进入页面即请求配置
			recruitConfigLoaded: false,
			// 请求中的标记，防止并发请求
			loadingRecruitConfig: false,
			// 图鉴相关
			showCodex: false,
			codexPartners: [],
			selectedPev: 1,
			// 积分兑换相关
			exchangeCount: 1,
			exchangeLetterPrice: 10000,
			// 五阶伙伴兑换相关
			exchangePartnerList: [],
			showExchangeConfirm: false,
			currentExchangePartner: null
		}
	},
	onLoad() {
		// 进入页面立即请求招募配置（不依赖登录状态）
		this.loadRecruitConfig()
	},
	// 新增：保证 H5/路由切换时也能触发配置请求
	onShow() {
		// 仅在配置未加载且当前没有请求中时，才发起请求
		if (!this.recruitConfigLoaded && !this.loadingRecruitConfig) {
			this.loadRecruitConfig()
		}
	},
	mounted() {
		// 仅在配置未加载且当前没有请求中时，才发起请求
		if (!this.recruitConfigLoaded && !this.loadingRecruitConfig) {
			this.loadRecruitConfig()
		}
	},
	computed: {
		// 最大可兑换数量
		maxExchangeCount() {
			const currentScore = this.$store.getters['items/inviteScore'] || 0
			return Math.floor(currentScore / this.exchangeLetterPrice)
		},
		// 是否可以兑换兑换令
		canExchangeLetter() {
			const currentScore = this.$store.getters['items/inviteScore'] || 0
			return currentScore >= this.exchangeCount * this.exchangeLetterPrice
		},
		// 是否可以兑换五阶伙伴
		canExchangePartner() {
			const currentLetters = this.$store.getters['items/partnerExchangeLetter'] || 0
			return currentLetters >= 100
		},
		// 过滤后的图鉴伙伴列表（按选中品阶）
		filteredCodexPartners() {
			if (this.selectedPev) {
				return this.codexPartners.filter(p => p.pev === this.selectedPev)
			}
			return this.codexPartners
		}
	},
	methods: {
		// async loadUserResources() { /* removed: unified to items module */ },

		// 加载招募配置（新接口，并适配可能的字段）
		async loadRecruitConfig() {
			// 防止重复请求：如果已加载或正在加载，直接返回
			if (this.recruitConfigLoaded || this.loadingRecruitConfig) {
				return
			}
			
			// 设置请求中标记
			this.loadingRecruitConfig = true
			try {
				const api = (await import('@/api')).default
				const response = await api.post('/partner/invite_config', {})
				if (response && response.code === 1 && response.data) {
					const data = response.data || {}
					const cfg = data.config || {}
					const normalCfg = cfg['1'] || {}
					const advCfg = cfg['2'] || {}

					// 统一：将返回的 coin1/coin2/invite_ling/scores 同步到 items 模块
					const updates = []
					if (typeof data.coin1 === 'number') updates.push([ITEM_ID.COIN, data.coin1])
					if (typeof data.coin2 === 'number') updates.push([ITEM_ID.GOLD_COIN, data.coin2])
					if (typeof data.invite_ling === 'number') updates.push([ITEM_ID.INVITE_LING, data.invite_ling])
					if (typeof data.scores === 'number') updates.push([ITEM_ID.INVITE_SCORE, data.scores])
					if (updates.length > 0) {
						this.$store.dispatch('items/applyItemsFromArray', updates)
					}

					// coin_type 与 speed
					this.coinTypeNormal = normalCfg.coin_type ?? 1
					this.coinTypeAdvanced = advCfg.coin_type ?? 2
					this.normalSpeedOne = normalCfg.speed?.['1'] ?? 0
					this.normalSpeedTen = normalCfg.speed?.['10'] ?? 0
					this.advancedSpeedOne = advCfg.speed?.['1'] ?? 0
					this.advancedSpeedTen = advCfg.speed?.['10'] ?? 0

					// 概率 percent 映射到原有结构，formatProb 同时兼容整数/小数
					const toProb = (arr) => ({
						green: (arr?.[0] ?? 0),
						blue: (arr?.[1] ?? 0),
						purple: (arr?.[2] ?? 0),
						orange: (arr?.[3] ?? 0)
					})
					this.recruitConfig = {
						normal: {
							cost: { coin1: this.normalSpeedOne },
							probabilities: toProb(normalCfg.percent)
						},
						advanced: {
							cost: { coin2: this.advancedSpeedOne },
							probabilities: toProb(advCfg.percent)
						},
						duplicate_points: this.recruitConfig.duplicate_points
					}
					
					// 保存兑换相关配置
					this.exchangeLetterPrice = data.partner_exchange_letter_price || 10000
					this.exchangePartnerList = data.partner_exchange_config || []

					this.networkError = false
					// 新增：标记已加载，避免重复请求
					this.recruitConfigLoaded = true
				} else {
					console.warn('获取招募配置失败:', response?.msg)
				}
			} catch (error) {
				console.error('加载招募配置失败:', error)
			} finally {
				// 无论成功或失败，都要清除请求中标记
				this.loadingRecruitConfig = false
			}
		},

		formatProb(prob) {
			return prob + '%'
		},
		
		// 图鉴相关方法
		async openCodex() {
			this.showCodex = true
			await this.loadCodex()
		},
		closeCodex() {
			this.showCodex = false
		},
		async loadCodex() {
			try {
				const api = (await import('@/api')).default
				const response = await api.sect.getPartnerPicture()
				if (response && response.code === 1 && response.data) {
					const hasPartner = response.data.hasPartner || {}
					// 转换为扁平数组
					const partners = []
					for (const [pevStr, partnerList] of Object.entries(hasPartner)) {
						const pev = parseInt(pevStr)
						if (Array.isArray(partnerList)) {
							for (const item of partnerList) {
								if (Array.isArray(item) && item.length >= 2) {
									const [name, owned] = item
									partners.push({
										name: String(name),
										pev: pev,
										owned: owned === 1 || owned === true
									})
								}
							}
						}
					}
					// 按品阶和名字排序
					partners.sort((a, b) => {
						if (a.pev !== b.pev) return a.pev - b.pev
						return a.name.localeCompare(b.name)
					})
					this.codexPartners = partners
				}
			} catch (error) {
				console.error('加载图鉴失败:', error)
				uni.showToast({ title: '加载图鉴失败', icon: 'none' })
			}
		},
		
		// 积分兑换相关方法
		increaseExchangeCount() {
			if (this.exchangeCount < this.maxExchangeCount) {
				this.exchangeCount++
			}
		},
		decreaseExchangeCount() {
			if (this.exchangeCount > 1) {
				this.exchangeCount--
			}
		},
		async exchangeLetter() {
			if (this.loading) return
			
			// 检查积分是否充足
			if (!this.canExchangeLetter) {
				const needScore = this.exchangeCount * this.exchangeLetterPrice
				const currentScore = this.$store.getters['items/inviteScore'] || 0
				uni.showToast({ 
					title: `积分不足，需要${this.formatNumber(needScore)}积分，当前${this.formatNumber(currentScore)}积分`, 
					icon: 'none',
					duration: 3000
				})
				return
			}
			
			try {
				this.loading = true
				const api = (await import('@/api')).default
				const response = await api.sect.getPartnerExchangeLetter(this.exchangeCount)
				if (response && response.code === 1) {
					uni.showToast({ title: response.msg || '兑换成功', icon: 'success' })
					// item会通过全局钩子自动更新
					this.exchangeCount = 1 // 重置为1
				} else {
					uni.showToast({ title: response?.msg || '兑换失败', icon: 'none' })
				}
			} catch (error) {
				console.error('兑换失败:', error)
				uni.showToast({ title: error.message || '网络错误', icon: 'none' })
			} finally {
				this.loading = false
			}
		},
		
		// 五阶伙伴兑换相关方法
		exchangePartnerConfirm(partner) {
			if (this.loading) return
			if (!this.canExchangePartner) {
				uni.showToast({ title: '兑换令不足，需要100个兑换令', icon: 'none' })
				return
			}
			this.currentExchangePartner = partner
			this.showExchangeConfirm = true
		},
		async doExchangePartner() {
			if (!this.currentExchangePartner || this.loading) return
			
			try {
				this.loading = true
				const api = (await import('@/api')).default
				const response = await api.sect.exchangePartner(this.currentExchangePartner.partner_id)
				if (response && response.code === 1) {
					uni.showToast({ title: response.msg || '兑换成功', icon: 'success' })
					// item会通过全局钩子自动更新
					// 如果图鉴已打开，也刷新图鉴数据
					if (this.showCodex) {
						await this.loadCodex()
					}
					this.showExchangeConfirm = false
					this.currentExchangePartner = null
				} else {
					uni.showToast({ title: response?.msg || '兑换失败', icon: 'none' })
				}
			} catch (error) {
				console.error('兑换失败:', error)
				uni.showToast({ title: error.message || '网络错误', icon: 'none' })
			} finally {
				this.loading = false
			}
		},
		checkPartnerOwnedByName(partnerName) {
			// 检查图鉴中的伙伴是否拥有（仅用于图鉴显示）
			if (this.codexPartners.length > 0 && partnerName) {
				const partner = this.codexPartners.find(p => p.name === partnerName)
				return partner ? partner.owned : false
			}
			return false
		},

		// 检查资源是否足够（按当前消耗配置）
		checkResources(type, count) {
			const costInfo = this.getCostInfo(type, count)
			for (const [resource, amount] of Object.entries(costInfo)) {
				const have = resource === 'invite_ling'
					? (this.$store.getters['items/inviteLing'] || 0)
					: (resource === 'coin1'
							? (this.$store.getters['items/coin'] || 0)
							: (this.$store.getters['items/goldCoin'] || 0))
				if (have < amount) {
					return false
				}
			}
			return true
		},

		// 获取消耗信息（后端配置 + 当前切换）
		getCostInfo(type, count) {
			if (type === 'normal') {
				if (count === 10) return { coin1: this.normalSpeedTen }
				return { coin1: this.normalSpeedOne }
			}
			if (type === 'advanced') {
				// 仅当单抽且有招募令时使用招募令；十连不使用招募令，由后端按金币扣除
				if (count === 1 && (this.$store.getters['items/inviteLing'] || 0) > 0) {
					return { invite_ling: 1 }
				}
				if (count === 10) return { coin2: this.advancedSpeedTen }
				return { coin2: this.advancedSpeedOne }
			}
			return {}
		},

		getCostName(key) {
			const nameMap = { coin1: '银两', coin2: '金元宝', invite_ling: '招募令' }
			return nameMap[key] || key
		},

		getRecruitTypeName(type) {
			const nameMap = { normal: '普通招募', advanced: '高级招募' }
			return nameMap[type] || type
		},

		getConfirmText(type, count) {
			const costInfo = this.getCostInfo(type, count)
			const costText = Object.entries(costInfo)
				.map(([key, value]) => `${this.getCostName(key)} x${value}`)
				.join(', ')
			return `确认消耗 ${costText} 进行${count}次${this.getRecruitTypeName(type)}？`
		},

		// 招募伙伴（新接口：/partner/invite）
		async recruit(type, count) {
			if (this.loading) return
			if (!this.checkLoginStatus()) return
			// 仅支持 1 或 10 次招募
			if (![1, 10].includes(count)) {
				uni.showToast({ title: '招募次数仅支持1或10', icon: 'none' })
				return
			}
			if (!this.checkResources(type, count)) {
				uni.showToast({ title: '资源不足', icon: 'none' })
				return
			}
			this.loading = true
			try {
				const api = (await import('@/api')).default
				// 后端参数为数字：type(1=普通,2=高级)和count(1或10)
				const typeMap = { normal: 1, advanced: 2 }
				const payload = { type: typeMap[type], count }
				const response = await api.post('/partner/invite', payload)
				if (response && response.code === 1) {
					// 后端返回数据结构：
					// { inviteScore: 1500, item: { "1": 925300, "2": 9995000, ... }, newPartnerName: ["丘处机:3", ...] }
					// 注意：item 对象会通过全局钩子自动更新，不需要手动处理，也不需要重新请求配置接口
					const nameStrings = response?.data?.newPartnerName || []
					const currentScore = response?.data?.inviteScore || 0  // 本次获得的积分
					
					// 解析伙伴名字字符串，构建伙伴信息对象
					const parsedPartners = this.parsePartnerNames(nameStrings)
					this.recruitResult = {
						partners: parsedPartners,
						new_count: parsedPartners.length,
						recruit_type: type,
						recruit_count: count, // 保存招募次数
						cost: this.getCostInfo(type, count),
						current_score: currentScore // 本次获得的积分
					}
					this.showResult = true
				} else {
					uni.showToast({ title: response?.msg || '招募失败', icon: 'none' })
				}
			} catch (error) {
				console.error('招募失败:', error)
				uni.showToast({ title: error.message || '网络错误', icon: 'none' })
			} finally {
				this.loading = false
			}
		},

		// 重试加载数据（去除积分加载）
		async retryLoadData() {
			this.networkError = false
			await this.loadRecruitConfig()
		},

		// 保留：登录检查、确认弹窗、关闭结果、跳转、头像与类型文案
		checkLoginStatus() {
			try {
				const yid = uni.getStorageSync('yid')
				const userId = uni.getStorageSync('userId')
				if (!yid || !userId) {
					uni.showToast({ title: '请先登录', icon: 'none' })
					setTimeout(() => { uni.reLaunch({ url: '/pages/login/index' }) }, 1200)
					return false
				}
				return true
			} catch (e) {
				console.error('检查登录状态失败:', e)
				return false
			}
		},
		showConfirm(title, content) {
			return new Promise((resolve) => {
				uni.showModal({ title, content, success: (res) => resolve(res.confirm), fail: () => resolve(false) })
			})
		},
		closeResult() { this.showResult = false },
		// 继续招募 - 在当前招募类型下继续请求后端（不关闭弹框，直接更新内容）
		async continueRecruit() {
			if (!this.recruitResult.recruit_type || !this.recruitResult.recruit_count) {
				this.closeResult()
				return
			}
			if (this.loading) return
			if (!this.checkLoginStatus()) return
			
			// 检查资源是否足够
			const type = this.recruitResult.recruit_type
			const count = this.recruitResult.recruit_count
			if (!this.checkResources(type, count)) {
				uni.showToast({ title: '资源不足', icon: 'none' })
				return
			}
			
			// 不关闭弹框，直接在后台执行招募
			this.loading = true
			try {
				const api = (await import('@/api')).default
				// 后端参数为数字：type(1=普通,2=高级)和count(1或10)
				const typeMap = { normal: 1, advanced: 2 }
				const payload = { type: typeMap[type], count }
				const response = await api.post('/partner/invite', payload)
				if (response && response.code === 1) {
					// 后端返回数据结构：
					// { inviteScore: 1500, item: { "1": 925300, "2": 9995000, ... }, newPartnerName: ["丘处机:3", ...] }
					// 注意：item 对象会通过全局钩子自动更新，不需要手动处理，也不需要重新请求配置接口
					const nameStrings = response?.data?.newPartnerName || []
					const currentScore = response?.data?.inviteScore || 0  // 本次获得的积分
					
					// 解析伙伴名字字符串，构建伙伴信息对象
					const parsedPartners = this.parsePartnerNames(nameStrings)
					// 直接更新结果数据，不关闭弹框
					this.recruitResult = {
						partners: parsedPartners,
						new_count: parsedPartners.length,
						recruit_type: type,
						recruit_count: count, // 保存招募次数
						cost: this.getCostInfo(type, count),
						current_score: currentScore // 本次获得的积分
					}
					// 弹框保持打开状态，只更新内容
				} else {
					uni.showToast({ title: response?.msg || '招募失败', icon: 'none' })
				}
			} catch (error) {
				console.error('招募失败:', error)
				uni.showToast({ title: error.message || '网络错误', icon: 'none' })
			} finally {
				this.loading = false
			}
		},
		// 获取招募次数文本
		getRecruitCountText(count) {
			if (count === 10) return '十连招募'
			if (count === 1) return '单次招募'
			return `${count}次招募`
		},
		goToPartners() { uni.navigateTo({ url: '/pages/partner/index' }) },
		goBack() { try { uni.navigateBack() } catch (e) { window.history.back() } },
		// 解析伙伴名字字符串数组，格式：["名字:品质等级"]
		parsePartnerNames(nameStrings) {
			if (!Array.isArray(nameStrings) || nameStrings.length === 0) return []
			
			return nameStrings.map(nameStr => {
				// 解析格式： "欧阳锋:3" -> { name: "欧阳锋", pev: 3 }
				const parts = String(nameStr).split(':')
				const name = parts[0] || '未知伙伴'
				const pev = parseInt(parts[1] || '1', 10) || 1
				
				// 品质映射：pev 1-5 对应 white, blue, purple, orange, red（按用户要求）
				const qualityMap = {
					1: 'white',
					2: 'blue',
					3: 'purple',
					4: 'orange',
					5: 'red'
				}
				const quality = qualityMap[pev] || 'white'
				
				// 构建伙伴信息对象（新获得的伙伴默认星级为0，需要从伙伴列表获取完整信息）
				return {
					name,
					pev,
					quality,
					avatar: 'default-avatar.svg', // 默认头像，后续可以根据名字从伙伴列表匹配
					star: 0, // 新获得的伙伴默认为0星
					type: null // 类型需要从伙伴详情获取，暂时不显示
				}
			})
		},
		
		getAvatarUrl(avatar) { 
			if (!avatar) return '/static/default-avatar.svg'
			return `/static/avatars/${avatar}` 
		},
		getTypeText(type) { 
			const m = { tank: '坦克', damage: '输出', healer: '治疗', control: '控制' }
			return m[type] || type || '' 
		},
		
		// 获取道具名称
		getItemName(itemId) {
			return ITEM_NAME[itemId] || `道具${itemId}`
		},
		
		// 格式化数字（添加千分位分隔符）
		formatNumber(num) {
			return Number(num).toLocaleString('zh-CN')
		}
	}
}
</script>

<style scoped>
.recruit-container {
	padding: 8px;
	background: linear-gradient(180deg, #f8f6f1 0%, #efe6d9 100%);
	min-height: 100vh;
	padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
}

/* ========== 统一头部样式 ========== */
.header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 8px;
	padding: 12px 15px;
	background: rgba(255, 255, 255, 0.98);
	border: 2px solid #c4a57b;
	border-radius: 12px;
	box-shadow: 0 3px 10px rgba(139, 111, 71, 0.2);
}

.back-btn {
	padding: 6px 12px;
	background: rgba(139, 111, 71, 0.1);
	border: 2px solid #c4a57b;
	border-radius: 8px;
	color: #4a3c2a;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	transition: all 0.3s ease;
}

.back-btn:hover {
	background: rgba(139, 111, 71, 0.2);
	border-color: #8b6f47;
}

.header-center {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.title {
	font-size: 18px;
	font-weight: 700;
	color: #4a3c2a;
	letter-spacing: 1px;
}

.placeholder {
	width: 70px;
}

/* ========== 压缩资源面板 ========== */
.currency-panel {
	background: rgba(255, 255, 255, 0.98);
	border: 2px solid #c4a57b;
	border-radius: 10px;
	padding: 8px 10px;
	margin-bottom: 8px;
	box-shadow: 0 2px 8px rgba(139, 111, 71, 0.15);
}

.currency-row {
	display: flex;
	justify-content: space-around;
	gap: 6px;
}

.currency-item {
	display: flex;
	align-items: center;
	gap: 4px;
	flex: 1;
	justify-content: center;
	padding: 5px;
	background: rgba(139, 111, 71, 0.05);
	border-radius: 8px;
	border: 1px solid #d8c7a3;
}

.currency-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	font-size: 11px;
	font-weight: 700;
	color: white;
	border: 2px solid;
}

.currency-icon.coin1 {
	background: linear-gradient(135deg, #c0c0c0 0%, #e8e8e8 100%);
	border-color: #9a9a9a;
	color: #333;
}

.currency-icon.coin2 {
	background: linear-gradient(135deg, #d4af37 0%, #ffd700 100%);
	border-color: #b8951f;
	color: #6b4f3b;
}

.currency-item > .currency-icon:not(.coin1):not(.coin2) {
	background: linear-gradient(135deg, #8b6f47 0%, #6b4f3b 100%);
	border-color: #4b3a2a;
}

.currency-value {
	font-size: 12px;
	font-weight: 700;
	color: #4a3c2a;
}

/* ========== 压缩招募选项区域 ========== */
.recruit-options {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* ========== 压缩招募卡片 ========== */
.recruit-card {
	background: rgba(255, 255, 255, 0.98);
	border: 2px solid #c4a57b;
	border-radius: 12px;
	padding: 12px;
	margin-bottom: 8px;
	box-shadow: 0 3px 10px rgba(139, 111, 71, 0.2);
	transition: all 0.3s ease;
}

.recruit-card:hover {
	transform: translateY(-1px);
	box-shadow: 0 4px 12px rgba(139, 111, 71, 0.3);
	border-color: #8b6f47;
}

.recruit-card.normal-recruit {
	border-left: 3px solid #6b8e67;
}

.recruit-card.premium-recruit {
	border-left: 3px solid #d4af37;
}

.card-header {
	margin-bottom: 10px;
	padding-bottom: 8px;
	border-bottom: 2px solid #e8dcc4;
}

.card-title {
	font-size: 16px;
	font-weight: 700;
	color: #4a3c2a;
	letter-spacing: 0.5px;
}

.cost-display {
	display: flex;
	align-items: center;
	gap: 6px;
	margin-bottom: 10px;
	padding: 8px;
	background: rgba(139, 111, 71, 0.06);
	border-radius: 6px;
	border: 1px solid #d8c7a3;
}

.cost-label {
	font-size: 12px;
	font-weight: 600;
	color: #8b6f47;
}

.cost-value {
	font-size: 13px;
	font-weight: 700;
	color: #4a3c2a;
}

/* 概率显示区域 */
.probability-section {
	margin-bottom: 24rpx;
}

.prob-title {
	font-size: 26rpx;
	color: #333;
	margin-bottom: 16rpx;
	font-weight: 500;
}

.probability-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 12rpx;
}

.prob-item {
	display: flex;
	align-items: center;
	padding: 12rpx 16rpx;
	background: #f8f9fa;
	border-radius: 8rpx;
	font-size: 24rpx;
	border: 1rpx solid #e9ecef;
}

.prob-color {
	width: 16rpx;
	height: 16rpx;
	border-radius: 50%;
	margin-right: 8rpx;
}

.prob-item.green .prob-color { background: #28a745; }
.prob-item.blue .prob-color { background: #007bff; }
.prob-item.purple .prob-color { background: #6f42c1; }
.prob-item.orange .prob-color { background: #fd7e14; }

.prob-item.green span { color: #28a745; }
.prob-item.blue span { color: #007bff; }
.prob-item.purple span { color: #6f42c1; }
.prob-item.orange span { color: #fd7e14; }

/* 消耗信息 */
.cost-section {
	margin-bottom: 24rpx;
}

.cost-item {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16rpx 24rpx;
	background: #fff3cd;
	border-radius: 8rpx;
	border: 1rpx solid #ffeaa7;
}

.cost-icon {
	font-size: 24rpx;
	margin-right: 8rpx;
	color: #856404;
}

.cost-text {
	font-size: 24rpx;
	font-weight: 500;
	color: #856404;
}

/* ========== 压缩招募按钮 ========== */
.recruit-buttons {
	display: flex;
	gap: 8px;
}

.recruit-btn {
	flex: 1;
	padding: 10px 8px;
	border-radius: 10px;
	border: 2px solid;
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
	transition: all 0.3s ease;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	box-shadow: 0 2px 8px rgba(139, 111, 71, 0.15);
	position: relative;
}

.primary-btn {
	background: linear-gradient(135deg, #6b8e67 0%, #5a7a56 100%);
	border-color: #4a6a46;
	color: white;
}

.primary-btn:hover:not(.disabled) {
	transform: translateY(-1px);
	box-shadow: 0 3px 10px rgba(107, 142, 103, 0.25);
}

.premium-btn {
	background: linear-gradient(135deg, #d4af37 0%, #b8951f 100%);
	border-color: #9a7a15;
	color: #6b4f3b;
}

.premium-btn:hover:not(.disabled) {
	transform: translateY(-1px);
	box-shadow: 0 3px 10px rgba(212, 175, 55, 0.25);
}

.btn-text {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.3px;
}

.btn-cost {
	font-size: 12px;
	opacity: 0.95;
	font-weight: 600;
}

.btn-bonus {
	font-size: 10px;
	background: rgba(255, 255, 255, 0.3);
	color: white;
	padding: 2px 6px;
	border-radius: 8px;
	font-weight: 700;
	margin-top: 1px;
}

.premium-btn .btn-bonus {
	color: #6b4f3b;
	background: rgba(255, 255, 255, 0.4);
}

.recruit-btn.disabled {
	opacity: 0.5;
	cursor: not-allowed;
	transform: none !important;
}

.recruit-btn.disabled:hover {
	transform: none !important;
	box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1) !important;
}

.probability-info {
	display: flex;
	flex-wrap: wrap;
	gap: 15rpx;
	margin-bottom: 20rpx;
}

.prob-item {
	font-size: 24rpx;
	padding: 6rpx 12rpx;
	border-radius: 12rpx;
	background-color: rgba(255,255,255,0.8);
	min-width: 60rpx;
	text-align: center;
}

.prob-item.green { color: #52c41a; }
.prob-item.blue { color: #1890ff; }
.prob-item.purple { color: #722ed1; }
.prob-item.orange { color: #fa8c16; }

.cost-info {
	display: flex;
	align-items: center;
	margin-bottom: 20rpx;
	min-height: 30rpx;
}

.cost-label {
	font-size: 26rpx;
	color: #333;
	margin-right: 10rpx;
}

.cost-value {
	font-size: 26rpx;
	font-weight: bold;
	color: #fa8c16;
}

.recruit-actions {
	display: flex;
	gap: 15rpx;
}

.recruit-btn:active {
	transform: scale(0.95);
}

.normal-btn {
	background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}

.advanced-btn {
	background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
}

.event-btn {
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.user-resources {
	display: flex;
	justify-content: space-around;
	background-color: white;
	border-radius: 15rpx;
	padding: 20rpx;
	margin-bottom: 20rpx;
	box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.08);
}

.resource-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8rpx;
}

.resource-icon {
	font-size: 32rpx;
}

.resource-name {
	font-size: 24rpx;
	color: #666;
}

.resource-count {
	font-size: 28rpx;
	font-weight: bold;
	color: #333;
}

/* 网络错误提示 */
.error-notice {
	background: #f8d7da;
	border-radius: 12rpx;
	padding: 20rpx;
	margin-bottom: 20rpx;
	border: 1rpx solid #f5c6cb;
}

.error-content {
	display: flex;
	align-items: center;
	justify-content: space-between;
	color: #721c24;
}

.error-icon {
	font-size: 28rpx;
	margin-right: 12rpx;
}

.error-text {
	flex: 1;
	font-size: 24rpx;
}

.error-actions {
	flex-shrink: 0;
}

.retry-btn {
	padding: 8rpx 16rpx;
	background: #dc3545;
	color: white;
	border-radius: 8rpx;
	font-size: 22rpx;
	cursor: pointer;
	transition: all 0.3s ease;
}

.retry-btn:hover {
	background: #c82333;
}

/* 活动招募卡片 */
.recruit-card .card-subtitle.inactive {
	color: #dc3545;
	font-weight: 500;
}

/* 招募说明 */
.recruit-instructions {
	background: white;
	border-radius: 16rpx;
	padding: 32rpx;
	margin-top: 24rpx;
	border: 1rpx solid #e9ecef;
	box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.08);
}

.instruction-header {
	margin-bottom: 20rpx;
	padding-bottom: 16rpx;
	border-bottom: 1rpx solid #e9ecef;
}

.instruction-title {
	font-size: 28rpx;
	font-weight: 600;
	color: #333;
}

.instruction-content {
	color: #666;
	line-height: 1.6;
	font-size: 24rpx;
	display: flex;
	flex-direction: column;
	gap: 15rpx;
}

.instruction-item {
	padding: 10rpx 0;
}

.instruction-text {
	font-size: 24rpx;
	color: #666;
	line-height: 1.6;
}

/* 响应式设计 */
@media (max-width: 750rpx) {
	.currency-grid {
		grid-template-columns: repeat(4, 1fr);
	}
	
	.probability-grid {
		grid-template-columns: 1fr;
	}
	
	.recruit-buttons {
		flex-direction: column;
	}
	
	.modal-content {
		width: 95%;
		padding: 30rpx 20rpx;
	}
	
	.score-value {
		font-size: 40rpx;
	}
	
	.partner-item {
		padding: 12rpx 16rpx;
		font-size: 24rpx;
	}
	
	.partner-name-text {
		font-size: 24rpx;
	}
}

/* 动画效果 - 移除游戏风格的发光效果 */
@keyframes subtle-hover {
	0% { transform: translateY(0); }
	100% { transform: translateY(-2rpx); }
}

.recruit-card:hover {
	animation: subtle-hover 0.3s ease;
}

.result-modal {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(0,0,0,0.5);
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 1000;
}

.modal-content {
	width: 90%;
	max-width: 600rpx;
	max-height: 85vh;
	background-color: white;
	border-radius: 20rpx;
	padding: 40rpx 30rpx;
	box-shadow: 0 10rpx 30rpx rgba(0,0,0,0.3);
	overflow-y: auto;
	animation: modalFadeIn 0.3s ease-out;
}

@keyframes modalFadeIn {
	from {
		transform: scale(0.9);
		opacity: 0;
	}
	to {
		transform: scale(1);
		opacity: 1;
	}
}

.modal-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 0;
	padding: 35rpx 30rpx;
	border-bottom: 3rpx solid #d8c7a3;
	background: linear-gradient(135deg, rgba(139, 111, 71, 0.15) 0%, rgba(107, 79, 59, 0.1) 100%);
}

.modal-title {
	font-size: 44rpx;
	font-weight: bold;
	color: #4b2e0f;
	letter-spacing: 3rpx;
	text-shadow: 2rpx 2rpx 4rpx rgba(75, 46, 15, 0.2);
	font-family: "STSong", "Noto Serif SC", serif;
}

.codex-content .modal-header {
	padding: 40rpx 35rpx;
}

.codex-content .modal-title {
	font-size: 48rpx;
	color: #3b2a12;
	letter-spacing: 4rpx;
}

.close-btn {
	width: 64rpx;
	height: 64rpx;
	border-radius: 50%;
	background: rgba(139, 111, 71, 0.2);
	border: 2rpx solid #d8c7a3;
	display: flex;
	justify-content: center;
	align-items: center;
	font-size: 42rpx;
	color: #5b4523;
	flex-shrink: 0;
	font-weight: bold;
	transition: all 0.3s;
	cursor: pointer;
}

.close-btn:hover {
	background: rgba(139, 111, 71, 0.3);
	border-color: #c29d5b;
	transform: rotate(90deg);
}

.codex-content .close-btn {
	background: rgba(255, 255, 255, 0.4);
	border-color: #8a6a3f;
	color: #4b2e0f;
}

/* 结果展示分区 */
.result-section {
	padding: 24rpx 0;
}

/* 招募类型描述区域 */
.recruit-type-section {
	padding: 20rpx 0;
	text-align: center;
	border-bottom: 2rpx solid #f0f0f0;
	margin-bottom: 20rpx;
}

.recruit-type-text {
	font-size: 32rpx;
	font-weight: bold;
	color: #4b3a2a;
	letter-spacing: 1rpx;
	padding: 16rpx 24rpx;
	background: linear-gradient(135deg, #f8f6f1 0%, #f5f1ea 100%);
	border-radius: 12rpx;
	border: 2rpx solid #e2d6bd;
	display: inline-block;
}

.score-section {
	text-align: center;
	padding: 32rpx 0;
}

.section-title {
	font-size: 28rpx;
	font-weight: 600;
	color: #333;
	margin-bottom: 16rpx;
}

.score-value {
	font-size: 48rpx;
	font-weight: bold;
	color: #FFD700; /* 金色 */
	text-shadow: 0 2rpx 4rpx rgba(255, 215, 0, 0.3);
	animation: scorePulse 0.6s ease-in-out;
}

@keyframes scorePulse {
	0% { transform: scale(0.8); opacity: 0; }
	50% { transform: scale(1.1); }
	100% { transform: scale(1); opacity: 1; }
}

.section-divider {
	height: 2rpx;
	background: linear-gradient(to right, transparent, #e0e0e0, transparent);
	margin: 24rpx 0;
}

/* 新伙伴展示区 */
.partners-section {
	padding: 24rpx 0;
}

.partners-list {
	display: flex;
	flex-direction: column;
	gap: 12rpx;
}

.partner-item {
	padding: 16rpx 20rpx;
	background: #f8f9fa;
	border-radius: 12rpx;
	text-align: center;
	animation: fadeInUp 0.5s ease-out;
}

.partner-item:nth-child(1) { animation-delay: 0.1s; }
.partner-item:nth-child(2) { animation-delay: 0.2s; }
.partner-item:nth-child(3) { animation-delay: 0.3s; }

@keyframes fadeInUp {
	from {
		transform: translateY(20rpx);
		opacity: 0;
	}
	to {
		transform: translateY(0);
		opacity: 1;
	}
}

.partner-name-text {
	font-size: 28rpx;
	font-weight: bold;
	display: inline-block;
}

/* 品阶颜色：1-白色，2-蓝色，3-紫色，4-橙色，5-红色 */
.partner-name-text.pev-1 {
	color: #c0c4cc; /* 白色 */
}

.partner-name-text.pev-2 {
	color: #1890ff; /* 蓝色 */
}

.partner-name-text.pev-3 {
	color: #722ed1; /* 紫色 */
}

.partner-name-text.pev-4 {
	color: #fa8c16; /* 橙色 */
}

.partner-name-text.pev-5 {
	color: #FF9800; /* 橙色 - 与QualityText组件保持一致 */
}

.partners-grid {
	max-height: 400rpx;
	margin-bottom: 20rpx;
}

.partner-result {
	display: inline-block;
	width: 150rpx;
	margin: 10rpx;
	text-align: center;
	vertical-align: top;
}

.result-avatar {
	position: relative;
	width: 120rpx;
	height: 120rpx;
	margin: 0 auto 10rpx;
	flex-shrink: 0;
}

.avatar-img {
	width: 100%;
	height: 100%;
	border-radius: 10rpx;
	object-fit: cover;
}

.quality-border {
	position: absolute;
	top: -3rpx;
	left: -3rpx;
	right: -3rpx;
	bottom: -3rpx;
	border: 3rpx solid;
	border-radius: 13rpx;
	pointer-events: none;
}

.quality-border.quality-white { border-color: #c0c4cc; }
.quality-border.quality-green { border-color: #52c41a; }
.quality-border.quality-blue { border-color: #1890ff; }
.quality-border.quality-purple { border-color: #722ed1; }
.quality-border.quality-orange { border-color: #fa8c16; }

.star-rating {
	position: absolute;
	bottom: -8rpx;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
}

.star {
	color: #ffd700;
	font-size: 18rpx;
	text-shadow: 1rpx 1rpx 2rpx rgba(0,0,0,0.3);
}

.partner-name {
	font-size: 24rpx;
	font-weight: bold;
	margin-bottom: 5rpx;
	display: block;
	line-height: 1.3;
	min-height: 32rpx;
}

.partner-name.quality-green { color: #52c41a; }
.partner-name.quality-blue { color: #1890ff; }
.partner-name.quality-purple { color: #722ed1; }
.partner-name.quality-orange { color: #fa8c16; }
.partner-name.quality-white { color: #c0c4cc; }

.pev-badge {
	position: absolute;
	bottom: -5rpx;
	right: -5rpx;
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
	color: white;
	font-size: 20rpx;
	padding: 4rpx 8rpx;
	border-radius: 8rpx;
	font-weight: 600;
	border: 2rpx solid white;
}

.no-partners {
	padding: 40rpx 20rpx;
	text-align: center;
	background: #f8f9fa;
	border-radius: 12rpx;
	margin-bottom: 20rpx;
}

.no-partners-text {
	font-size: 26rpx;
	color: #666;
	line-height: 1.6;
}

.partner-type {
	font-size: 20rpx;
	color: #666;
	line-height: 1.2;
	min-height: 24rpx;
}

.result-actions {
	display: flex;
	gap: 20rpx;
}

.result-btn {
	flex: 1;
	padding: 20rpx;
	border-radius: 12rpx;
	text-align: center;
	font-size: 28rpx;
	font-weight: bold;
	color: white;
	background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}

.continue-btn {
	background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
}

.loading-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(0,0,0,0.5);
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 999;
}

.loading-content {
	background-color: white;
	padding: 60rpx;
	border-radius: 20rpx;
	text-align: center;
}

.loading-text {
	font-size: 32rpx;
	color: #333;
	margin-bottom: 30rpx;
	display: block;
}

.loading-animation {
	display: flex;
	justify-content: center;
	gap: 10rpx;
}

.loading-dot {
	font-size: 40rpx;
	color: #667eea;
	animation: bounce 1.4s ease-in-out infinite both;
}

.loading-dot:nth-child(1) { animation-delay: -0.32s; }
.loading-dot:nth-child(2) { animation-delay: -0.16s; }

@keyframes bounce {
	0%, 80%, 100% {
		transform: scale(0);
	}
	40% {
		transform: scale(1.0);
	}
}

/* ========== 压缩兑换区域 ========== */
.exchange-section, .partner-exchange-section {
	margin-top: 8px;
	margin-bottom: 8px;
	padding: 12px;
	background: rgba(255, 255, 255, 0.98);
	border: 2px solid #c4a57b;
	border-radius: 12px;
	box-shadow: 0 3px 10px rgba(139, 111, 71, 0.2);
}

.section-title {
	font-size: 15px;
	font-weight: 700;
	color: #4a3c2a;
	margin-bottom: 10px;
	text-align: center;
	letter-spacing: 1px;
	padding-bottom: 8px;
	border-bottom: 2px solid #e8dcc4;
}

.exchange-content {
	margin-top: 10px;
}

/* ========== 压缩积分兑换卡片 ========== */
.exchange-card {
	background: rgba(248, 246, 241, 0.8);
	border-radius: 10px;
	padding: 10px;
	border: 2px solid #d8c7a3;
	box-shadow: 0 2px 8px rgba(139, 111, 71, 0.12);
}

.exchange-info {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 8px;
	padding: 8px;
	background: rgba(139, 111, 71, 0.06);
	border-radius: 6px;
}

.exchange-name {
	font-size: 13px;
	font-weight: 700;
	color: #4a3c2a;
}

.exchange-price {
	font-size: 12px;
	font-weight: 600;
	color: #8b6f47;
}

.exchange-controls {
	display: flex;
	align-items: center;
	gap: 8px;
}

.count-btn {
	width: 28px;
	height: 28px;
	border-radius: 6px;
	border: 2px solid #c4a57b;
	background: rgba(255, 255, 255, 0.9);
	color: #4a3c2a;
	font-size: 14px;
	font-weight: 700;
	cursor: pointer;
	transition: all 0.3s ease;
}

.count-btn:hover:not(:disabled) {
	background: rgba(139, 111, 71, 0.1);
	border-color: #8b6f47;
}

.count-btn:disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.count-display {
	flex: 1;
	text-align: center;
	font-size: 13px;
	font-weight: 700;
	color: #4a3c2a;
	padding: 0 8px;
}

.exchange-btn {
	padding: 6px 16px;
	background: linear-gradient(135deg, #8b6f47 0%, #6b4f3b 100%);
	border: 2px solid #4b3a2a;
	border-radius: 8px;
	color: white;
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
	transition: all 0.3s ease;
}

.exchange-btn:hover:not(:disabled) {
	transform: translateY(-1px);
	box-shadow: 0 2px 8px rgba(75, 58, 42, 0.25);
}

.exchange-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

/* ========== 压缩五阶伙伴兑换区域 ========== */
.exchange-info-bar {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin-bottom: 10px;
	padding: 8px;
	background: rgba(139, 111, 71, 0.08);
	border-radius: 6px;
	border: 1px solid #d8c7a3;
}

.info-label {
	font-size: 12px;
	font-weight: 600;
	color: #8b6f47;
}

.info-value {
	font-size: 13px;
	font-weight: 700;
	color: #4a3c2a;
}

.info-divider {
	color: #c4a57b;
	margin: 0 4px;
}

.info-text {
	font-size: 11px;
	color: #6b4f3b;
	font-weight: 600;
}

.partner-exchange-list {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 8px;
}

.partner-exchange-card {
	background: rgba(248, 246, 241, 0.9);
	border: 2px solid #d8c7a3;
	border-radius: 10px;
	padding: 10px;
	text-align: center;
	transition: all 0.3s ease;
}

.partner-exchange-card:hover {
	border-color: #c4a57b;
	box-shadow: 0 2px 8px rgba(139, 111, 71, 0.15);
	transform: translateY(-1px);
}

.partner-name {
	font-size: 14px;
	font-weight: 700;
	margin-bottom: 6px;
	letter-spacing: 0.3px;
}

.partner-name.pev-5 {
	color: #FF9800;
}

.partner-desc {
	font-size: 11px;
	color: #6b4f3b;
	margin-bottom: 8px;
	line-height: 1.3;
}

.exchange-partner-btn {
	width: 100%;
	padding: 6px;
	background: linear-gradient(135deg, #d4af37 0%, #b8951f 100%);
	border: 2px solid #9a7a15;
	border-radius: 8px;
	color: #6b4f3b;
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
	transition: all 0.3s ease;
}

.exchange-partner-btn:hover:not(:disabled) {
	transform: translateY(-1px);
	box-shadow: 0 2px 8px rgba(212, 175, 55, 0.25);
}

.exchange-partner-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
	background: #d0d0d0;
	border-color: #999;
	color: #666;
}

.no-partner-text {
	text-align: center;
	padding: 25px 15px;
	color: #8b6f47;
	font-size: 13px;
	font-weight: 600;
}

.card-header {
	display: flex;
	align-items: center;
	gap: 24rpx;
	margin-bottom: 35rpx;
	padding-bottom: 30rpx;
	border-bottom: 3rpx solid #e2d6bd;
}

.card-icon {
	font-size: 64rpx;
	width: 100rpx;
	height: 100rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(135deg, #f5e6d3 0%, #e2d6bd 100%);
	border-radius: 16rpx;
	border: 2rpx solid #d8c7a3;
	box-shadow: 0 4rpx 12rpx rgba(75, 58, 42, 0.1);
}

.card-info {
	flex: 1;
}

.card-title {
	font-size: 40rpx;
	font-weight: bold;
	color: #4b3a2a;
	margin-bottom: 12rpx;
	letter-spacing: 1rpx;
}

.card-desc {
	font-size: 28rpx;
	color: #8b6f47;
	font-weight: 500;
}

.card-body {
	display: flex;
	flex-direction: column;
	gap: 30rpx;
}

.cost-info {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 25rpx;
	background: linear-gradient(135deg, #f8f6f1 0%, #f5f1ea 100%);
	border-radius: 16rpx;
	border: 2rpx solid #e2d6bd;
}

.cost-label {
	font-size: 28rpx;
	color: #6b4f3b;
}

.cost-value {
	display: flex;
	align-items: baseline;
	gap: 8rpx;
}

.cost-number {
	font-size: 44rpx;
	font-weight: bold;
	color: #8b6f47;
	text-shadow: 1rpx 1rpx 2rpx rgba(0, 0, 0, 0.1);
}

.cost-unit {
	font-size: 28rpx;
	color: #6b4f3b;
}

.exchange-action {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 30rpx;
}

.exchange-count-input {
	display: flex;
	align-items: center;
	gap: 16rpx;
	background: #f8f6f1;
	padding: 10rpx;
	border-radius: 12rpx;
	border: 2rpx solid #d8c7a3;
}

.count-btn {
	width: 70rpx;
	height: 70rpx;
	border: 2rpx solid #8b6f47;
	background: #fff;
	color: #6b4f3b;
	border-radius: 10rpx;
	font-size: 36rpx;
	font-weight: bold;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: all 0.3s;
	box-shadow: 0 4rpx 8rpx rgba(75, 58, 42, 0.15);
}

.count-btn:active {
	transform: scale(0.95);
	background: #f5f1ea;
}

.count-btn:disabled {
	opacity: 0.4;
	cursor: not-allowed;
	background: #f5f5f5;
	border-color: #d0d0d0;
	color: #999;
}

.count-input {
	width: 140rpx;
	height: 70rpx;
	border: 2rpx solid #d8c7a3;
	border-radius: 10rpx;
	text-align: center;
	font-size: 32rpx;
	font-weight: bold;
	color: #4b3a2a;
	background: #fff;
}

.exchange-btn {
	flex: 1;
	height: 80rpx;
	background: linear-gradient(135deg, #8b6f47 0%, #6b4f3b 100%);
	color: #6311af;
	border: 2rpx solid #4b3a2a;
	border-radius: 12rpx;
	font-size: 32rpx;
	font-weight: bold;
	box-shadow: 0 6rpx 16rpx rgba(75, 58, 42, 0.3),
		inset 0 2rpx 4rpx rgba(255, 255, 255, 0.2);
	transition: all 0.3s;
	letter-spacing: 1rpx;
}

.exchange-btn:active {
	transform: translateY(2rpx);
	box-shadow: 0 4rpx 12rpx rgba(75, 58, 42, 0.25);
}

.exchange-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
	background: #ccc;
	border-color: #999;
	pointer-events: none;
}

.exchange-btn:not(:disabled) {
	cursor: pointer;
}

.exchange-summary {
	display: flex;
	flex-direction: column;
	gap: 16rpx;
	padding: 25rpx;
	background: #f8f6f1;
	border-radius: 12rpx;
	border: 2rpx solid #e2d6bd;
}

.summary-item {
	display: flex;
	justify-content: space-between;
	align-items: center;
	font-size: 28rpx;
}

.summary-label {
	color: #6b4f3b;
}

.summary-value {
	color: #4b3a2a;
	font-weight: 500;
}

.summary-value.highlight {
	color: #8b6f47;
	font-weight: bold;
	font-size: 32rpx;
}

/* 五阶伙伴兑换信息卡片 */
.exchange-info-card {
	background: linear-gradient(135deg, #f8f6f1 0%, #f5f1ea 100%);
	border-radius: 20rpx;
	padding: 35rpx;
	border: 3rpx solid #e2d6bd;
	box-shadow: 0 6rpx 20rpx rgba(75, 58, 42, 0.12);
	margin-bottom: 35rpx;
}

.info-card-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 25rpx;
	padding-bottom: 25rpx;
	border-bottom: 2rpx solid #e2d6bd;
}

.info-label {
	font-size: 32rpx;
	color: #4b3a2a;
	font-weight: 500;
}

.info-value {
	font-size: 52rpx;
	font-weight: bold;
	color: #8b6f47;
	text-shadow: 1rpx 1rpx 2rpx rgba(0, 0, 0, 0.1);
}

.info-card-rule {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12rpx;
	padding: 20rpx;
	background: rgba(255, 255, 255, 0.6);
	border-radius: 12rpx;
	border: 2rpx dashed #d8c7a3;
}

.rule-icon {
	font-size: 32rpx;
}

.rule-text {
	font-size: 28rpx;
	color: #6b4f3b;
	font-weight: 500;
}

/* 伙伴卡片样式 */
.partner-exchange-list {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 30rpx;
}

.partner-card {
	position: relative;
	background: linear-gradient(135deg, #fff 0%, #f8f6f1 100%);
	border-radius: 20rpx;
	padding: 35rpx 30rpx;
	border: 3rpx solid #e2d6bd;
	box-shadow: 0 8rpx 24rpx rgba(75, 58, 42, 0.15);
	transition: all 0.3s;
	overflow: hidden;
}

.partner-card::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.3) 0%, transparent 60%);
	pointer-events: none;
}

.partner-card:hover {
	transform: translateY(-6rpx);
	box-shadow: 0 12rpx 32rpx rgba(75, 58, 42, 0.25);
	border-color: #d8c7a3;
}

.partner-card.owned {
	opacity: 0.7;
	background: linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%);
}

.card-border {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	border-radius: 20rpx;
	border: 1rpx solid rgba(216, 199, 163, 0.3);
	pointer-events: none;
}

.partner-card-header {
	margin-bottom: 30rpx;
	padding-bottom: 25rpx;
	border-bottom: 2rpx dashed #e2d6bd;
}

.partner-info {
	display: flex;
	flex-direction: column;
	gap: 16rpx;
}

.partner-name {
	font-size: 36rpx;
	font-weight: bold;
	letter-spacing: 1rpx;
}

/* 五阶伙伴名称颜色 - 使用全局五阶颜色 */
.partner-name.pev-5 {
	color: #FF9800; /* 橙色 - 与QualityText组件保持一致 */
}

.partner-desc {
	font-size: 26rpx;
	color: #6b4f3b;
	line-height: 1.6;
	padding: 12rpx 16rpx;
	background: rgba(139, 111, 71, 0.08);
	border-radius: 8rpx;
	border-left: 3rpx solid #d8c7a3;
	margin-top: 4rpx;
}

.partner-card-body {
	display: flex;
	flex-direction: column;
	gap: 24rpx;
}

.card-requirement {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10rpx;
	padding: 16rpx;
	background: #f8f6f1;
	border-radius: 10rpx;
	border: 1rpx solid #e2d6bd;
}

.req-icon {
	font-size: 28rpx;
}

.req-text {
	font-size: 26rpx;
	color: #6b4f3b;
	font-weight: 500;
}

.partner-exchange-btn {
	width: 100%;
	height: 76rpx;
	background: linear-gradient(135deg, #8b6f47 0%, #6b4f3b 100%);
	color: #fff;
	border: 2rpx solid #4b3a2a;
	border-radius: 12rpx;
	font-size: 30rpx;
	font-weight: bold;
	box-shadow: 0 4rpx 12rpx rgba(75, 58, 42, 0.25),
		inset 0 1rpx 3rpx rgba(255, 255, 255, 0.2);
	transition: all 0.3s;
	letter-spacing: 1rpx;
	position: relative;
	z-index: 1;
}

.partner-exchange-btn:active {
	transform: translateY(2rpx);
	box-shadow: 0 2rpx 8rpx rgba(75, 58, 42, 0.2);
}

.partner-exchange-btn.disabled {
	opacity: 0.5;
	cursor: not-allowed;
	background: #d0d0d0;
	border-color: #999;
	color: #666;
	box-shadow: none;
	pointer-events: none;
}

.partner-exchange-btn:not(.disabled):not(.owned) {
	cursor: pointer;
}

.partner-exchange-btn.owned {
	background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%);
	border-color: #529b2e;
}

.no-partner-text {
	text-align: center;
	color: #8b6f47;
	font-size: 32rpx;
	padding: 60rpx 40rpx;
	background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(248, 246, 241, 0.8) 100%);
	border-radius: 16rpx;
	border: 2rpx dashed #d8c7a3;
	margin-top: 30rpx;
}

/* 图鉴弹窗样式 - 武侠风格优化 */
.codex-modal {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.7);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 1000;
	backdrop-filter: blur(4rpx);
}

.codex-content {
	max-width: 92%;
	max-height: 85vh;
	display: flex;
	flex-direction: column;
	background: linear-gradient(180deg, #f7f2e7 0%, #efe6d9 100%);
	border-radius: 24rpx;
	border: 3rpx solid #d8c7a3;
	box-shadow: 0 16rpx 48rpx rgba(75, 58, 42, 0.4),
		inset 0 2rpx 8rpx rgba(255, 255, 255, 0.3);
	overflow: hidden;
}

.codex-body {
	flex: 1;
	overflow-y: auto;
	padding: 40rpx 30rpx;
	background: rgba(255, 255, 255, 0.3);
}

.codex-filter {
	display: flex;
	flex-wrap: wrap;
	gap: 20rpx;
	margin-bottom: 40rpx;
	padding-bottom: 30rpx;
	border-bottom: 3rpx solid #d8c7a3;
	justify-content: center;
}

.filter-btn {
	padding: 18rpx 36rpx;
	background: rgba(255, 255, 255, 0.9);
	border: 2rpx solid #d8c7a3;
	border-radius: 12rpx;
	font-size: 30rpx;
	font-weight: 600;
	color: #5b4523;
	letter-spacing: 1rpx;
	transition: all 0.3s;
	box-shadow: 0 4rpx 8rpx rgba(75, 58, 42, 0.1);
}

.filter-btn:active {
	transform: scale(0.95);
}

.filter-btn.active {
	background: linear-gradient(135deg, #8b6f47 0%, #6b4f3b 100%);
	color: #fff;
	border-color: #4b3a2a;
	box-shadow: 0 6rpx 16rpx rgba(75, 58, 42, 0.3),
		inset 0 2rpx 4rpx rgba(255, 255, 255, 0.2);
	font-weight: bold;
}

.codex-list {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24rpx;
}

.codex-partner-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 24rpx 16rpx;
	background: rgba(255, 255, 255, 0.95);
	border-radius: 16rpx;
	border: 2rpx solid #d8c7a3;
	box-shadow: 0 4rpx 12rpx rgba(75, 58, 42, 0.15);
	transition: all 0.3s;
	min-height: 100rpx;
	position: relative;
	overflow: hidden;
}

.codex-partner-item::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.4) 0%, transparent 60%);
	pointer-events: none;
}

.codex-partner-item:hover {
	transform: translateY(-4rpx);
	box-shadow: 0 8rpx 20rpx rgba(75, 58, 42, 0.25);
	border-color: #c29d5b;
}

.codex-partner-item.owned {
	background: linear-gradient(135deg, rgba(255, 255, 255, 0.98) 0%, rgba(248, 246, 241, 0.98) 100%);
	border-color: #c29d5b;
}

.codex-partner-item.unowned {
	opacity: 0.65;
	background: linear-gradient(135deg, rgba(245, 245, 245, 0.9) 0%, rgba(235, 235, 235, 0.9) 100%);
}

.codex-partner-name {
	font-size: 28rpx;
	font-weight: 600;
	text-align: center;
	word-break: break-all;
	letter-spacing: 1rpx;
	position: relative;
	z-index: 1;
	line-height: 1.4;
}

.codex-partner-name.unowned {
	color: #CCCCCC;
	font-weight: 400;
}

.codex-empty {
	text-align: center;
	color: #8a6a3f;
	font-size: 32rpx;
	padding: 100rpx 40rpx;
	font-style: italic;
	letter-spacing: 2rpx;
}

/* 兑换确认弹窗样式 */
.confirm-modal {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.6);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 1001;
}

.confirm-content {
	max-width: 80%;
}

.confirm-body {
	padding: 40rpx 30rpx;
}

.confirm-text {
	font-size: 32rpx;
	color: #333;
	text-align: center;
	line-height: 1.6;
	margin-bottom: 40rpx;
}

.confirm-text .highlight {
	color: #667eea;
	font-weight: bold;
}

.confirm-actions {
	display: flex;
	gap: 20rpx;
}

.confirm-btn {
	flex: 1;
	height: 80rpx;
	border: none;
	border-radius: 10rpx;
	font-size: 30rpx;
	font-weight: bold;
}

.confirm-btn.cancel {
	background: #f5f5f5;
	color: #666;
}

.confirm-btn.confirm {
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
	color: #fff;
}

/* ========== 压缩底部操作按钮 ========== */
.bottom-actions {
	margin-top: 8px;
	margin-bottom: 8px;
	padding: 10px;
	display: flex;
	justify-content: center;
}

.codex-btn {
	padding: 10px 25px;
	background: linear-gradient(135deg, #8b6f47 0%, #6b4f3b 100%);
	color: white;
	border: 2px solid #4b3a2a;
	border-radius: 12px;
	font-size: 14px;
	font-weight: 700;
	box-shadow: 0 3px 10px rgba(75, 58, 42, 0.25);
	transition: all 0.3s ease;
	letter-spacing: 0.5px;
	cursor: pointer;
}

.codex-btn:hover {
	transform: translateY(-1px);
	box-shadow: 0 4px 12px rgba(75, 58, 42, 0.35);
	border-color: #6b4f3b;
}

.codex-btn:active {
	transform: translateY(0);
}
</style>